package myClient.handler;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import myClient.session.ClientSession;
import org.springframework.stereotype.Service;
import protobuf.Serialization.HeartBeatMsgConverter;
import protobuf.protoClass.ProtoMsg;

import java.util.concurrent.TimeUnit;

/**
 * 定时发送心跳信息
 */

@ChannelHandler.Sharable
@Service("HeartBeatClientHandler")
public class HeartBeatClientHandler extends ChannelInboundHandlerAdapter {

    /**
     * 心跳信息，发送间隔时间
     */
    public static final int HEARTBEAT_INTERVAL = 20;

    /**
     * 在 Handler被加入到 Pipeline时，开始发送心跳
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        //获取 Session
        ClientSession session = ClientSession.getSessionByContext(ctx);
        //创建 心跳信息
        ProtoMsg.Message heatBeatMessage = HeartBeatMsgConverter.build(session);
        //发送
        heatBeat(ctx, heatBeatMessage);
    }

    /**
     * 循环，定时发送心跳信息
     *
     * @param heatBeatMessage 心跳信息
     */
    public void heatBeat(ChannelHandlerContext ctx, ProtoMsg.Message heatBeatMessage) {
        //定时任务
        ctx.executor().schedule(() -> {
            if (ctx.channel().isActive()) {
                System.out.println("发送 HEART_BEAT  消息 to server");
                //信息写入并 flush
                ctx.writeAndFlush(heatBeatMessage);
                //循环
                heatBeat(ctx, heatBeatMessage);
            }
        }, HEARTBEAT_INTERVAL, TimeUnit.SECONDS);
    }

    /**
     * 处理服务器 Server发来的信息，过滤出 {@link ProtoMsg.MessageHeartBeat}类型信息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //判断消息实例
        if (!(msg instanceof ProtoMsg.Message protoMsg_Message)) {
            super.channelRead(ctx, msg);
            return;
        }
        //判断类型
        ProtoMsg.HeadType headType = protoMsg_Message.getType();
        if (headType.equals(ProtoMsg.HeadType.HEART_BEAT)) {
            System.out.println(" 收到回写的 HEART_BEAT  消息 from server");
        } else {
            super.channelRead(ctx, msg);
        }
    }

}
